package widget.common.managers
{
	import com.rworld.common.utils.MyLog;
	
	import flash.display.InteractiveObject;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	
	import mx.controls.TextArea;
	import mx.controls.TextInput;
	import mx.core.Application;
	
	/**
	 * 键盘管理器 
	 * @author 黄子真
	 * 
	 */	
	public class KeyboardManager implements IManager
	{
	    /**
         * Singleton instance 
        */
        private static var instance:KeyboardManager;
        /**
         * downKeys is an array of the keys that are down
         **/
        public var downKeys:Array = [];
        private var keyDic:Dictionary = null;
         
        public function KeyboardManager(sig:SingletonKey){
        	keyDic = new Dictionary();
        	addKeyboardListener();
        }
        
        /**
         * Returns the Singleton instance of KeyboardManager
         */
        public static function getInstance() : KeyboardManager
        {
            if (instance == null)
            {
                instance = new KeyboardManager(new SingletonKey());
            }
            return instance;
        }
        
         /**
         * downKeyCodes is an array of just the keycodes
         **/
        public function getDownKeyCodes():Array
        {
            var a:Array = [];
            for (var i:Number = 0; i < downKeys.length; i++)
            {
                a.push(downKeys[i].keyCode);
            }
            return a;
        }
         
        
        public function doKeyDown(event:KeyboardEvent):void
        {
            //doesContain is a boolean for telling whether or not, 
            //the number is in the array
            var doesContain:Boolean = false;
            
            //tempKeyCode is used to prevent the first keyDown from being added twice
            //i'm sure there are better ways to do this other than
            //creating a temp variable, but it's late and i'm tired.
            var isFirstItem:Boolean = false;
            
            if(downKeys.length == 0)
            {
                downKeys.push(event);
                isFirstItem = true;
            }
            else
            {
                //keyDown
                for(var i:int = 0; i < downKeys.length; i++)
                {
                    if(downKeys[i].keyCode == event.keyCode)
                    {
                        doesContain = true;
                        i = downKeys.length;
                        break;
                    }
                }
            }
            
            if( doesContain == false && isFirstItem == false)
            {
                downKeys.push(event);
            }
            
        }
        
        public function keyUpHandle(event:KeyboardEvent):void
        {
            //keyUp
            var doesContain:Boolean = false;
            var indexOfItem:Number = 0;
            
            for(var i:int = 0; i < downKeys.length; i++)
            {
                if(downKeys[i].keyCode == event.keyCode)
                {
                    indexOfItem = i;
                    doesContain = true;
                    i = downKeys.length;
                    break;
                }
            }
            
            if( doesContain == true )
            {
                //remove the item that was found
                downKeys.splice(indexOfItem,1);
            }
        }
        /**
         * 判断该键是否被按下 
         * @param searchKeyCode
         * @return 
         * 
         */        
        public function isKeyDown(searchKeyCode:uint):Boolean
        {
            var isFound:Boolean = false;
            
            for(var j:int = 0; j < downKeys.length; j++)
            {
                var evt:KeyboardEvent = downKeys[j] as KeyboardEvent;
                if(evt.keyCode == searchKeyCode)
                {
                    isFound = true;
                }
                else
                {
                    isFound = false;
                }
            }
            return isFound;
        }
        /**
         * 注册对应键值的处理函数 
         * @param key
         * @param fun
         * 
         */        
        public function registerListener(key:uint,fun:Function):void{
        	keyDic[key] = fun;
        }
        /**
         * 添加键盘管理器的监听 
         * 
         */        
        public function addKeyboardListener():void{
        	Application.application.stage.addEventListener(FocusEvent.FOCUS_IN,focusInHandler);
        	Application.application.stage.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE,keyFocusHandler);
        	Application.application.stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandle);
        	Application.application.stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandle);
        }
        
        /**
         * 清除键盘管理器所有监听 
         * 
         */        
        public function delKeyboardListener():void{
        	Application.application.stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownHandle);
        	Application.application.stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpHandle);
        	/* for(var i:* in keyDic){
        		delete keyDic[i];
        	} */
        }
        /**
         * 移除指定键值的处理方法
         * @param code
         * 
         */        
        public function removeListenerByCode(code:int):void{
        	delete keyDic[code];
        }
        
        private function keyFocusHandler(e:FocusEvent):void{
        	if(e.target is TextArea || e.target is TextField || e.target is TextInput){
        		Application.application.stage.focus = null;
				addKeyboardListener();
        	}
		}
		private function focusInHandler(e:FocusEvent):void{
			if(e.target is TextArea || e.target is TextField || e.target is TextInput){
				if(e.target is InteractiveObject){
					var tag:InteractiveObject = InteractiveObject(e.target);
					Application.application.stage.focus = tag;
				}
				delKeyboardListener();
			}
		}
        /**
         * 判断该键值是否注册 
         * @param code
         * @return 
         * 
         */        
        private function isContain(code:int):Boolean{
        	var tem:Boolean = false;
        	for(var i:* in keyDic){
        		if(i == code){
        			tem = true;
        			break;		
        		}
        	}
        	return tem;
        }
        
        private function keyDownHandle(eve:KeyboardEvent):void{
        	var code:uint = eve.keyCode;
        	var fun:Function = null;
        	doKeyDown(eve);
        	if(isContain(code) && isKeyDown(code)){
        		fun = keyDic[code];
        		if(fun != null){
        			fun.call(null,eve);
        		}
        	}
        }
        
        public function dispose():void
        {
        	
        }
	}
}
class SingletonKey{}
		